﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using PluginSample2.BarModel;
using StockModel;
using Visiblox.Charts;

namespace PluginSample2
{
	internal partial class DailyChart : UserControl
	{
		#region Attributes

		private IEnumerable<Bar> _bars;
		private IEnumerable<Operation> _operations;

		#endregion

		#region Properties

		public DataSeries<DateTime, decimal> MinMaxValues { get; private set; }

		public DateTime Day
		{
			set
			{
				this.Chart.Title = value.Date.ToShortDateString();
			}
		}

		#endregion

		#region Public Methods

		public DailyChart()
		{
			this.MinMaxValues = new DataSeries<DateTime, decimal>("Min - Max values");
			
			InitializeComponent();
		}

		public void Initialize(IEnumerable<Operation> operations, IEnumerable<Bar> bars, DateTime day, bool includeOperations)
		{
			_operations = operations;
			_bars = bars;

			this.Day = day;

			this.GenerateData(includeOperations);
		}

		#endregion

		#region Private Methods

		private void GenerateData(bool includeOperations)
		{
			DailyChartPoints points = this.GenerateChartPoints();
			
			this.MinMaxValues.AddRange(points.MinMaxValues);

			if (includeOperations)
			{
				foreach (DataPoint<DateTime, decimal> operation in points.Operations)
				{
					this.Chart.Annotations.Add(new VerticalLineAnnotation(new DataPoint<DateTime, Decimal>(operation.X, operation.Y)) { AnnotationElementStyle = (Style)Resources["OperationVerticalLineStyle"] });
				}
			}

			this.Chart.Series[0].DataSeries = this.MinMaxValues;
		}

		private DailyChartPoints GenerateChartPoints()
		{
			DailyChartPoints result = new DailyChartPoints();

			foreach (Bar bar in _bars)
			{
				Dictionary<object, decimal> data = new Dictionary<object, decimal>();
				data.Add(CandlestickSeries.High, bar.Maximum);
				data.Add(CandlestickSeries.Low, bar.Minimum);
				data.Add(CandlestickSeries.Open, bar.Open);
				data.Add(CandlestickSeries.Close, bar.Close);

				result.MinMaxValues.Add(new MultiValuedDataPoint<DateTime, decimal>(bar.Start, data));
			}

			foreach (Operation operation in _operations)
			{
				// ReSharper disable PossibleInvalidOperationException
				result.Operations.Add(new DataPoint<DateTime, decimal>(operation.BuyDate, operation.BuyPrice));
				result.Operations.Add(new DataPoint<DateTime, decimal>(operation.SellDate, operation.SellPrice));
				// ReSharper restore PossibleInvalidOperationException
			}

			return result;
		}

		#endregion
	}
}
